package com.erli.exchange.common.aspect;

import java.lang.reflect.Method;
import java.security.InvalidParameterException;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import com.erli.exchange.common.validate.ModelValidAopHelper;
import com.erli.exchange.common.validate.ValidateRequestBodyWrapper;
import com.erli.exchange.core.util.JSRValidation;

import cn.hutool.json.JSONUtil;

@Aspect
@Component
@Order(2)
public class ValidAspect {

    private static Logger  logger = LoggerFactory.getLogger(ValidAspect.class);
    
	@Pointcut("@annotation(com.erli.exchange.common.annotation.ApiRequestMethod)")
	public void apiRequestPointCut() { 
		
	}
	
    @Before("apiRequestPointCut()")
    public void doBefore(JoinPoint joinPoint) throws Exception {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        Object[] args = joinPoint.getArgs();
        
        ValidateRequestBodyWrapper validateRequestBodyWrapper = ModelValidAopHelper.findValidateRequestBodyWrapper(method, args);
        if (validateRequestBodyWrapper != null) {
        	Object requestBody = validateRequestBodyWrapper.getRequestBody();
        	if (requestBody != null) {
        		String requestBodyContent = JSONUtil.toJsonStr(requestBody);
        		JSRValidation.ValidationResult validationResult = JSRValidation.validateEntity(requestBody, validateRequestBodyWrapper.getGroupClass());
        		if (validationResult.isHasErrors()) {
        			logger.info("check param {}", requestBodyContent);
        			throw new InvalidParameterException(validationResult.getErrorMsg().values().stream().findFirst().get());
        		}
        	}
        }
    }

}
